package com.getpebble.android.framework.util;

import com.getpebble.android.common.core.trace.Trace;
import com.getpebble.android.framework.protocol.outbound.PblOutboundMessage;
import com.google.common.base.Strings;
import com.google.common.primitives.UnsignedInteger;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.UUID;

public class ByteUtils {
    private static final Charset ASCII = Charset.forName("US-ASCII");
    private static final byte[] ELLIPSIS_BYTES = "\u2026".getBytes(UTF8);
    private static final byte[] HEXBYTES = new byte[]{(byte) 48, (byte) 49, (byte) 50, (byte) 51, (byte) 52, (byte) 53, (byte) 54, (byte) 55, (byte) 56, (byte) 57, (byte) 97, (byte) 98, (byte) 99, (byte) 100, (byte) 101, (byte) 102};
    private static final Random RAND = new Random();
    public static final String TAG = ByteUtils.class.getSimpleName();
    private static final Charset UTF8 = Charset.forName("UTF-8");

    private ByteUtils() {
    }

    public static UnsignedInteger getUint8FromBuffer(ByteBuffer b) {
        return UnsignedInteger.fromIntBits(b.get() & 255);
    }

    public static UnsignedInteger getUint16FromBuffer(ByteBuffer b) {
        return UnsignedInteger.fromIntBits(b.getShort() & 65535);
    }

    public static UnsignedInteger getUint32FromBuffer(ByteBuffer b) {
        return UnsignedInteger.fromIntBits(b.getInt());
    }

    public static int getStringLengthBytes(String s) {
        return s.getBytes(UTF8).length;
    }

    public static byte[] int2uint16LittleEndian(int i) {
        return new byte[]{(byte) (i & 255), (byte) ((i >> 8) & 255)};
    }

    public static String getStringFromBuffer(ByteBuffer b, int length) {
        String result;
        ByteBuffer stringBufferMaster = b.duplicate();
        int newLimit = b.position() + length;
        if (newLimit < 0 || newLimit > b.capacity()) {
            Trace.error(TAG, String.format("Invalid buffer limit; newLimit=%d, capacity=%d", new Object[]{Integer.valueOf(newLimit), Integer.valueOf(b.capacity())}));
            return "";
        }
        stringBufferMaster.limit(newLimit);
        b.position(b.position() + length);
        ByteBuffer stringBuffer = stringBufferMaster.duplicate();
        int nullTerminatorIdx;
        try {
            result = UTF8.newDecoder().decode(stringBuffer).toString();
            nullTerminatorIdx = result.indexOf(0);
            if (nullTerminatorIdx >= 0) {
                return result.substring(0, nullTerminatorIdx);
            }
            return result;
        } catch (CharacterCodingException e) {
            Trace.error(TAG, "Failed to decode string via " + UTF8.toString(), e);
            Trace.error(TAG, hexDump(stringBuffer));
            if (null != null) {
                return null;
            }
            stringBuffer = stringBufferMaster.duplicate();
            try {
                result = ASCII.newDecoder().decode(stringBuffer).toString();
                nullTerminatorIdx = result.indexOf(0);
                if (nullTerminatorIdx >= 0) {
                    return result.substring(0, nullTerminatorIdx);
                }
                return result;
            } catch (CharacterCodingException e2) {
                Trace.error(TAG, "Failed to decode string via " + ASCII.toString(), e2);
                Trace.error(TAG, hexDump(stringBuffer));
                if (null == null) {
                    return "";
                }
                return null;
            }
        }
    }

    public static byte[] getFixedLengthString(String str, int length) throws IllegalArgumentException {
        if (str == null) {
            str = "";
        }
        byte[] outputBuffer = new byte[length];
        byte[] strBytes = str.getBytes(UTF8);
        if (strBytes.length > length) {
            throw new IllegalArgumentException("String exceeds maximum length");
        }
        Arrays.fill(outputBuffer, (byte) 0);
        for (int i = 0; i < strBytes.length; i++) {
            outputBuffer[i] = strBytes[i];
        }
        return outputBuffer;
    }

    public static void writeFixedLengthString(PblOutboundMessage msg, String str, int length) throws IllegalArgumentException {
        msg.addBytes(getStringAsByteArray(str, length));
    }

    public static byte[] getStringAsByteArray(String str, int length) throws IllegalArgumentException {
        byte[] outputBuffer = new byte[length];
        byte[] strBytes = str.getBytes(UTF8);
        if (strBytes.length > length) {
            throw new IllegalArgumentException("String exceeds maximum length");
        }
        Arrays.fill(outputBuffer, (byte) 0);
        for (int i = 0; i < strBytes.length; i++) {
            outputBuffer[i] = strBytes[i];
        }
        return outputBuffer;
    }

    public static void writeNullTerminatedString(PblOutboundMessage msg, String str) {
        if (getStringLengthBytes(str) > 254) {
            str = new String(Arrays.copyOf(str.getBytes(UTF8), 254 - ELLIPSIS_BYTES.length));
        }
        writeFixedLengthString(msg, str, getStringLengthBytes(str) + 1);
    }

    public static void writePascalString(PblOutboundMessage msg, String str) {
        writePascalString(msg, str, 255);
    }

    static byte[] getStringBytes(CharSequence str, int maxBytes) {
        byte[] bytes = new byte[maxBytes];
        ByteBuffer outBuf = ByteBuffer.wrap(bytes);
        CharBuffer strBuf = CharBuffer.wrap(str);
        CharsetEncoder encoder = UTF8.newEncoder();
        outBuf.limit(maxBytes - ELLIPSIS_BYTES.length);
        if (encoder.encode(strBuf, outBuf, false) == CoderResult.OVERFLOW) {
            outBuf.limit(maxBytes);
            outBuf.mark();
            if (encoder.encode(strBuf, outBuf, true) == CoderResult.OVERFLOW) {
                outBuf.reset();
                while (true) {
                    outBuf.mark();
                    int overwrite = outBuf.get();
                    outBuf.reset();
                    if ((overwrite & 192) != 128) {
                        break;
                    }
                    try {
                        outBuf.position(outBuf.position() - 1);
                    } catch (IllegalArgumentException e) {
                        Trace.warning(TAG, "Error doing utf8-safe truncation", e);
                        return new byte[0];
                    }
                }
                outBuf.put(ELLIPSIS_BYTES);
            }
        } else {
            encoder.encode(strBuf, outBuf, true);
        }
        int size = outBuf.position();
        byte[] retBytes = new byte[size];
        for (int i = 0; i < size; i++) {
            retBytes[i] = bytes[i];
        }
        return retBytes;
    }

    public static void writePascalString(PblOutboundMessage msg, String str, int maxBytes) {
        if (ELLIPSIS_BYTES.length > maxBytes) {
            throw new IllegalArgumentException("maxBytes must be at least " + ELLIPSIS_BYTES.length);
        } else if (maxBytes > 255) {
            throw new IllegalArgumentException("maxBytes too large");
        } else if (Strings.isNullOrEmpty(str)) {
            msg.addBytes(Byte.valueOf((byte) 0));
        } else {
            msg.addBytes(Byte.valueOf((byte) getStringBytes(str, maxBytes).length));
            msg.addBytes(bytes);
        }
    }

    public static byte[] getUtf8StringList(List<CharSequence> strings, int maxBytes) {
        if (strings == null) {
            return new byte[0];
        }
        ByteBuffer outBuf = ByteBuffer.allocate(maxBytes);
        boolean hadStringBefore = false;
        for (CharSequence str : strings) {
            if (str != null) {
                CharBuffer strBuf = CharBuffer.wrap(str);
                CharsetEncoder encoder = UTF8.newEncoder();
                outBuf.limit(maxBytes - ELLIPSIS_BYTES.length);
                if (hadStringBefore) {
                    encoder.encode(CharBuffer.wrap("\u0000"), outBuf, false);
                }
                if (encoder.encode(strBuf, outBuf, false) == CoderResult.OVERFLOW) {
                    outBuf.limit(maxBytes);
                    outBuf.mark();
                    if (encoder.encode(strBuf, outBuf, true) == CoderResult.OVERFLOW) {
                        outBuf.reset();
                        while (true) {
                            outBuf.mark();
                            int overwrite = outBuf.get();
                            outBuf.reset();
                            if ((overwrite & 192) != 128) {
                                break;
                            }
                            try {
                                outBuf.position(outBuf.position() - 1);
                            } catch (IllegalArgumentException e) {
                                Trace.warning(TAG, "Error doing utf8-safe truncation", e);
                                return new byte[0];
                            }
                        }
                        outBuf.put(ELLIPSIS_BYTES);
                    }
                } else {
                    encoder.encode(strBuf, outBuf, false);
                }
                hadStringBefore = true;
            }
        }
        byte[] outBytes = new byte[outBuf.position()];
        outBuf.position(0);
        outBuf.get(outBytes);
        return outBytes;
    }

    public static byte[] getUtf8String(CharSequence str, int maxBytes) {
        if (str == null) {
            return new byte[0];
        }
        return getStringBytes(str, maxBytes);
    }

    public static String hexDump(ByteBuffer b) {
        ByteBuffer buf = b.duplicate();
        StringBuilder sb = new StringBuilder();
        while (buf.remaining() > 0) {
            sb.append(String.format("%02x ", new Object[]{Byte.valueOf(buf.get())}));
        }
        return sb.toString();
    }

    public static String hexDump(byte[] bb) {
        StringBuilder sb = new StringBuilder();
        int len$ = bb.length;
        for (int i$ = 0; i$ < len$; i$++) {
            sb.append(String.format("%02x ", new Object[]{Byte.valueOf(arr$[i$])}));
        }
        return sb.toString().substring(0, sb.length() - 1);
    }

    public static boolean getBooleanFromBuffer(ByteBuffer b) {
        return getUint8FromBuffer(b).compareTo(UnsignedInteger.ZERO) > 0;
    }

    public static byte[] getBytesFromBuffer(ByteBuffer bb, int count) {
        byte[] result = new byte[count];
        bb.get(result);
        return result;
    }

    public static String byteArrayToHexString(byte[] b) {
        StringBuilder sb = new StringBuilder();
        for (byte b2 : b) {
            int c = b2 & 255;
            sb.append((char) HEXBYTES[(c >> 4) & 15]).append((char) HEXBYTES[c & 15]).append(' ');
        }
        return sb.toString();
    }

    public static String byteArrayToHexStringCondensed(byte[] b) {
        StringBuilder sb = new StringBuilder();
        for (byte b2 : b) {
            int c = b2 & 255;
            sb.append((char) HEXBYTES[(c >> 4) & 15]).append((char) HEXBYTES[c & 15]);
        }
        return sb.toString();
    }

    public static byte[] int2bytes(int i) {
        return new byte[]{(byte) ((i >> 24) & 255), (byte) ((i >> 16) & 255), (byte) ((i >> 8) & 255), (byte) (i & 255)};
    }

    public static byte[] short2bytes(short s) {
        return new byte[]{(byte) ((s >> 8) & 255), (byte) (s & 255)};
    }

    public static byte[] unsignedInt2bytes(UnsignedInteger i, ByteOrder order) {
        return ByteBuffer.allocate(4).order(order).putInt(i.intValue()).array();
    }

    public static byte[] unsignedShort2bytes(UnsignedInteger i, ByteOrder order) {
        return ByteBuffer.allocate(2).order(order).putShort(i.shortValue()).array();
    }

    public static byte[] unsignedInt2bytes(UnsignedInteger i) {
        return unsignedInt2bytes(i, ByteOrder.BIG_ENDIAN);
    }

    public static byte unsignedInt2byte(UnsignedInteger i) {
        return (byte) (i.intValue() & 255);
    }

    public static byte[] unsignedInt2bytesLittleEndian(UnsignedInteger i) {
        return ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(i.intValue()).array();
    }

    public static byte[] randomCookie() {
        return int2bytes(RAND.nextInt());
    }

    public static UUID bytes2uuid(ByteBuffer buffer) {
        ByteBuffer b = buffer.duplicate();
        b.order(ByteOrder.BIG_ENDIAN);
        UUID result = new UUID(b.getLong(), b.getLong());
        buffer.position(b.position());
        return result;
    }

    public static byte[] uuid2bytes(UUID uuid) {
        byte[] bytes = new byte[16];
        ByteBuffer b = ByteBuffer.wrap(bytes);
        b.order(ByteOrder.BIG_ENDIAN);
        b.putLong(uuid.getMostSignificantBits());
        b.putLong(uuid.getLeastSignificantBits());
        Trace.debug(TAG, hexDump(bytes));
        return bytes;
    }

    public static String MD5DigestStringFromInputFQPN(String fullyQualifiedPathName) {
        Exception e;
        Throwable th;
        InputStream src = null;
        try {
            InputStream src2 = new FileInputStream(fullyQualifiedPathName);
            try {
                String MD5DigestStringFromInputStream = MD5DigestStringFromInputStream(src2);
                if (src2 == null) {
                    return MD5DigestStringFromInputStream;
                }
                try {
                    src2.close();
                    return MD5DigestStringFromInputStream;
                } catch (IOException e2) {
                    try {
                        Trace.debug(TAG, "MD5DigestStringFromInputFQPN", e2);
                        return MD5DigestStringFromInputStream;
                    } catch (Exception e3) {
                        e = e3;
                        src = src2;
                        Trace.debug(TAG, "MD5DigestStringFromInputFQPN", e);
                        return "";
                    }
                }
            } catch (Throwable th2) {
                th = th2;
                src = src2;
                if (src != null) {
                    try {
                        src.close();
                    } catch (IOException e22) {
                        Trace.debug(TAG, "MD5DigestStringFromInputFQPN", e22);
                    }
                }
                try {
                    throw th;
                } catch (Exception e4) {
                    e = e4;
                    Trace.debug(TAG, "MD5DigestStringFromInputFQPN", e);
                    return "";
                }
            }
        } catch (Throwable th3) {
            th = th3;
            if (src != null) {
                src.close();
            }
            throw th;
        }
    }

    public static String MD5DigestStringFromInputStream(InputStream src) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] devNullBuff = new byte[4096];
            do {
            } while (new DigestInputStream(src, md).read(devNullBuff, 0, devNullBuff.length) > 0);
            byte[] digest = md.digest();
            if (digest != null) {
                return byteArrayToHexStringCondensed(digest);
            }
        } catch (Exception e) {
        }
        return "";
    }
}
